package com.diorsunion.hedge.quota;

import com.diorsunion.hedge.dal.entity.stock.Stock;
import com.diorsunion.hedge.dal.entity.stock.StockPrice;
import com.diorsunion.hedge.util.CollectionTools;
import com.diorsunion.hedge.util.MathUtils;
import com.google.common.collect.Lists;
import org.springframework.util.CollectionUtils;

import java.util.Arrays;
import java.util.List;

/**
 * 布林带指标计算
 * 布林带指标公式
 * 1）计算标准差MD
     MD= 平方根N日的（C－MA）的两次方之和除以N
     其中MA=N日平均值
     3）计算MB、UP、DN线
     MB=（N－1）日的MA
     UP=MB +2*MD
     DN=MB -2*MD
 * Created by harley-dog on 2016/5/3.
 */
public class BollFilter implements StockPriceExFilter {
    public final int n ,k;

    public BollFilter(int n, int k) {
        this.n = n;
        this.k = k;
    }

    @Override
    public void filter(Stock stock, List<StockPrice> lastList, List<StockPrice> stockPriceList) {
        int start = CollectionUtils.isEmpty(lastList)?0:lastList.size();
        List<StockPrice> stockPriceAll = Lists.newArrayList();
        if(!CollectionUtils.isEmpty(lastList)){
            stockPriceAll.addAll(lastList);
        }
        stockPriceAll.addAll(stockPriceList);

        for(int i=start;i<stockPriceAll.size();i++){
            StockPrice stockPrice = stockPriceAll.get(i);
            //先计算标准差MD
            int d = 0;
            List<Double> closes = Lists.newArrayList();
            for(int j=i;j>=0 && d<n;j--,d++){
                StockPrice s = stockPriceAll.get(j);
                closes.add(s.close);
            }
            if (closes.size() >= 2) {
                double[] a = CollectionTools.toDoubleArray(closes);
                double[] a0 = Arrays.copyOfRange(a, 0, a.length - 1);
                double[] a1 = Arrays.copyOfRange(a, 1, a.length);
                double ma0 = MathUtils.avg(a0);
                double md = MathUtils.std(a1);
                //然后计算上一日的MB
                double mb = ma0;
                double up = mb + k*md;
                double dn = mb - k*md;
                stockPrice.ex.bollUp = up;
                stockPrice.ex.bollMid = mb;
                stockPrice.ex.bollLow = dn;
            }

        }
    }


}
